home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Newswatcher 2.0b22 / NW Source / Source / prefsdlog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-07  |  53.1 KB  |  1,938 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     prefsdlog.c
  4.  
  5.     This module handles the preferences dialog.
  6.     
  7.     Copyright © 1994, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <Packages.h>
  14. #include <Aliases.h>
  15. #include <Processes.h>
  16.  
  17. #include "glob.h"
  18. #include "prefsdlog.h"
  19. #include "dialog.h"
  20. #include "popuputil.h"
  21. #include "sfutil.h"
  22. #include "log.h"
  23. #include "news.h"
  24. #include "newswatcher.h"
  25. #include "strutil.h"
  26. #include "full.h"
  27. #include "drawutil.h"
  28. #include "memutil.h"
  29. #include "fileutil.h"
  30. #include "apputil.h"
  31. #include "resutil.h"
  32. #include "menus.h"
  33. #include "url.h"
  34. #include "ic.h"
  35.  
  36.  
  37.  
  38. /* Items common to all topics. The kInit and kTerm items are pseudo-items
  39.    used to intialize and terminate the topics. The OK and Cancel buttons
  40.    are also common to all topics (item numbers 1 and 2). Items 3 through
  41.    7 are user items to draw the 5 segments of the gray outline. Item 8
  42.    is the topic popup menu. Item 9 is the user item to outline the OK
  43.    button. */
  44.  
  45. #define kInit                100
  46. #define kTerm                101
  47. #define kFirstGrayLine        3
  48. #define kLastGrayLine        7
  49. #define kTopicPopup            8
  50. #define kCommonItems        9
  51.  
  52. /* Prefs dialog and DITL resources */
  53.  
  54. #define kPrefsDlg                300
  55. #define kNewsreadingOptions        1
  56. #define kServerAddresses        2
  57. #define kServerOptions            3
  58. #define kPersonalInfo            4
  59. #define kSignature                5
  60. #define kMessageOptions            6
  61. #define kExtraHeaderLines        7
  62. #define kRemoteHost                8
  63. #define kScreenFonts            9
  64. #define kPrintingFont            10
  65. #define kSavedUserGroupLists    11
  66. #define kSavedArticles            12
  67. #define kSavedMessages            13
  68. #define kURLHelpers1            14
  69. #define kURLHelpers2            15
  70. #define kAuthentication            16
  71. #define kExtractBinaries        17
  72. #define kMiscOptions            18
  73.  
  74. /* Newsreading options topic. */
  75.  
  76. #define kShowAuthors            (kCommonItems + 1)
  77. #define kShowArtHeaders            (kCommonItems + 2)
  78. #define kCollapseThreads        (kCommonItems + 3)
  79. #define kKeyboardShortcuts        (kCommonItems + 4)
  80. #define kKeypadShortcuts        (kCommonItems + 5)
  81. #define kReuseArticleWinds        (kCommonItems + 6)
  82. #define kReturnToSubjectWindow    (kCommonItems + 7)
  83. #define kBeepAtEndOfGroup        (kCommonItems + 8)
  84. #define kMaxArticles            (kCommonItems + 10)
  85.  
  86. /* Server info topic. */
  87.  
  88. #define kNewsServer            (kCommonItems + 3)
  89. #define kMailServer            (kCommonItems + 5)
  90.  
  91. /* Server options topic. */
  92.  
  93. #define kBatchedGroupCmds    (kCommonItems + 2)
  94. #define kUseXPAT            (kCommonItems + 3)
  95. #define kNoNewConnection    (kCommonItems + 4)
  96. #define kNoModeReader        (kCommonItems + 5)
  97.  
  98. /* Personal info topic. */
  99.  
  100. #define kFullName            (kCommonItems + 3)
  101. #define kOrganization        (kCommonItems + 5)
  102. #define kMailAddress        (kCommonItems + 7)
  103.  
  104. /* Signature topic. */
  105.  
  106. #define kSigStaticText        (kCommonItems + 1)
  107. #define kSignatureEditText    (kCommonItems + 2)
  108. #define kAddSigBlankLine    (kCommonItems + 3)
  109. #define kAddSigSeparator    (kCommonItems + 4)
  110.  
  111. /* Message options topic. */
  112.  
  113. #define kMsgReplyPost        (kCommonItems + 1)
  114. #define kMsgReplyEmail        (kCommonItems + 2)
  115. #define kMsgCopySelf        (kCommonItems + 3)
  116. #define kMsgShowMsgDetails    (kCommonItems + 4)
  117. #define kMsgWrapOnSend        (kCommonItems + 5)
  118. #define kMsgTabEnabled        (kCommonItems + 6)
  119. #define kMsgTabStops        (kCommonItems + 8)
  120. #define kMsgQuoteString        (kCommonItems + 10)
  121.  
  122. /* Extra header lines topic */
  123.  
  124. #define kMsgExtraNewsHdrLines    (kCommonItems + 2)
  125. #define kMsgExtraMailHdrLines    (kCommonItems + 4)
  126.  
  127. /* Remote host info topic. */
  128.  
  129. #define    kRemoteHostAddr        (kCommonItems + 3)
  130. #define    kRemoteLogin        (kCommonItems + 5)
  131. #define    kRemotePassword        (kCommonItems + 7)
  132. #define kRemotePath            (kCommonItems + 9)
  133. #define kAutoGetPut            (kCommonItems + 10)
  134. #define    kSavePassword        (kCommonItems + 11)
  135.  
  136. /* Screen fonts topic. */
  137.  
  138. #define kListFontPopup         (kCommonItems + 2)
  139. #define kListSizeBox        (kCommonItems + 4)
  140. #define kListSizePopup        (kCommonItems + 5)
  141. #define kListSample            (kCommonItems + 6)
  142. #define kListVertLine        (kCommonItems + 7)
  143. #define kTextFontPopup        (kCommonItems + 9)
  144. #define kTextSizeBox        (kCommonItems + 11)
  145. #define kTextSizePopup        (kCommonItems + 12)
  146. #define kTextSample            (kCommonItems + 13)
  147.  
  148. /* Printing font topic. */
  149.  
  150. #define kPrintingFontPopup         (kCommonItems + 1)
  151. #define kPrintingSizeBox        (kCommonItems + 3)
  152. #define kPrintingSizePopup        (kCommonItems + 4)
  153. #define kPrintingSample            (kCommonItems + 5)
  154.  
  155. /* Saved user group lists topic. */
  156.  
  157. #define kSavedUGLDirCheckBox    (kCommonItems + 1)
  158. #define kSavedUGLDirBorder        (kCommonItems + 2)
  159. #define kSavedUGLDirName        (kCommonItems + 3)
  160. #define kSavedUGLDirButton        (kCommonItems + 4)
  161. #define kSavedUGLAutoSaveOnQuit    (kCommonItems + 5)
  162.  
  163. /* Saved articles topic. */
  164.  
  165. #define kSavedArtAppBorder        (kCommonItems + 2)
  166. #define kSavedArtAppName        (kCommonItems + 3)
  167. #define kSavedArtAppButton        (kCommonItems + 4)
  168. #define kSavedArtDirCheckBox     (kCommonItems + 5)
  169. #define kSavedArtDirBorder        (kCommonItems + 6)
  170. #define kSavedArtDirName        (kCommonItems + 7)
  171. #define kSavedArtDirButton        (kCommonItems + 8)
  172. #define kSavedArtSepFiles        (kCommonItems + 9)
  173. #define kSavedArtAutoAppend        (kCommonItems + 10)
  174. #define kSavedArtSaveEncoded    (kCommonItems + 11)
  175.  
  176. /* Saved messages topic. */
  177.  
  178. #define kSavedMsgDirCheckBox     (kCommonItems + 1)
  179. #define kSavedMsgDirBorder        (kCommonItems + 2)
  180. #define kSavedMsgDirName        (kCommonItems + 3)
  181. #define kSavedMsgDirButton        (kCommonItems + 4)
  182. #define kSavedMsgDelAfterSend    (kCommonItems + 5)
  183.  
  184. /* URL helper programs 1 topic. */
  185.  
  186. #define kFTPAppBorder        (kCommonItems + 1)
  187. #define kFTPAppName            (kCommonItems + 2)
  188. #define kFTPAppButton        (kCommonItems + 3)
  189. #define kHTTPAppBorder        (kCommonItems + 5)
  190. #define kHTTPAppName        (kCommonItems + 6)
  191. #define kHTTPAppButton        (kCommonItems + 7)
  192. #define kGopherAppBorder    (kCommonItems + 9)
  193. #define kGopherAppName        (kCommonItems + 10)
  194. #define kGopherAppButton    (kCommonItems + 11)
  195. #define kWAISAppBorder        (kCommonItems + 13)
  196. #define kWAISAppName        (kCommonItems + 14)
  197. #define kWAISAppButton        (kCommonItems + 15)
  198.  
  199. /* URL helper programs 2 topic. */
  200.  
  201. #define kTelnetAppBorder    (kCommonItems + 1)
  202. #define kTelnetAppName        (kCommonItems + 2)
  203. #define kTelnetAppButton    (kCommonItems + 3)
  204. #define ktn3270AppBorder    (kCommonItems + 5)
  205. #define ktn3270AppName        (kCommonItems + 6)
  206. #define ktn3270AppButton    (kCommonItems + 7)
  207. #define kFingerAppBorder    (kCommonItems + 9)
  208. #define kFingerAppName        (kCommonItems + 10)
  209. #define kFingerAppButton    (kCommonItems + 11)
  210. #define kWhoisAppBorder        (kCommonItems + 13)
  211. #define kWhoisAppName        (kCommonItems + 14)
  212. #define kWhoisAppButton        (kCommonItems + 15)
  213.  
  214. /* Authentication topic. */
  215.  
  216. #define kAuthUsername        (kCommonItems + 3)
  217. #define kAuthPassword        (kCommonItems + 5)
  218. #define kAuthSavePassword    (kCommonItems + 6)
  219. #define kAuthPrivateGroups    (kCommonItems + 7)
  220. #define kAuthWhenRequested    (kCommonItems + 8)
  221. #define kAuthAtStartup        (kCommonItems + 9)
  222.  
  223. /* Extracting Binaries topic. */
  224.  
  225. #define kSavedBinDirCheckBox    (kCommonItems + 1)
  226. #define kSavedBinDirBorder        (kCommonItems + 2)
  227. #define kSavedBinDirName        (kCommonItems + 3)
  228. #define kSavedBinDirButton        (kCommonItems + 4)
  229. #define kHqxAppBorder            (kCommonItems + 6)
  230. #define kHqxAppName                (kCommonItems + 7)
  231. #define kHqxAppButton            (kCommonItems + 8)
  232. #define kUUAppBorder            (kCommonItems + 10)
  233. #define kUUAppName                (kCommonItems + 11)
  234. #define kUUAppButton            (kCommonItems + 12)
  235.  
  236. /* Miscellaneous options topic. */
  237.  
  238. #define kReZoomWindows            (kCommonItems + 1)
  239. #define kCheckNewGroups            (kCommonItems + 2)
  240. #define kAreYouSure                (kCommonItems + 3)
  241. #define kLogActionsToFile        (kCommonItems + 4)
  242. #define kDontCoverFinderIcons    (kCommonItems + 5)
  243. #define kUseInternetConfig        (kCommonItems + 6)
  244.  
  245.  
  246.  
  247. static Str255 gStaticText;        /* static text for signature dialog */
  248.  
  249. static short gListFontID;        /* current list font id */
  250. static short gListFontSize;        /* current list font size */
  251. static short gTextFontID;        /* current text font id */
  252. static short gTextFontSize;        /* current text font size */
  253. static short gPrintingFontID;    /* current printing font id */
  254. static short gPrintingFontSize;    /* current printing font size */
  255.  
  256. static Boolean gScreenFontsTopic;    /* true if screen fonts topic, false if printing font topic */
  257.  
  258. static FileFilterYDUPP gInvisibleFilesFilterUPP = nil;
  259. static UserItemUPP gDrawFontSampleUPP = nil;
  260.  
  261.  
  262.  
  263. /*----------------------------------------------------------------------------
  264.     ValidHelper
  265.  
  266.     Check for a valid helper program.
  267.     
  268.     Entry:    fSpec = pointer to helper program file spec.
  269.     
  270.     Exit:    function result = true if helper is valid.
  271.             *fSpec = pointer to file spec for copy of helper program which
  272.                 will actually be used if duplicate copies of helper found.
  273. ----------------------------------------------------------------------------*/
  274.  
  275. static Boolean ValidHelper (FSSpec *fSpec)
  276. {
  277.     OSErr err = noErr;
  278.     FInfo fInfo;
  279.     FSSpec file;
  280.     CStr255 fmt, msg;
  281.  
  282.     err = FSpGetFInfo(fSpec, &fInfo);
  283.     if (err != noErr) goto exit1;
  284.     if (fInfo.fdType != 'APPL') goto exit2;
  285.     err = FindAppFromSig(fInfo.fdCreator, &file, nil, nil);
  286.     if (err == fnfErr) goto exit3;
  287.     if (err != noErr) goto exit1;
  288.     if (!IsEqualFSSpec(fSpec, &file)) goto exit4;
  289.     return true;
  290.     
  291. exit1:
  292.     
  293.     GetCString(kStrUnexpectedErr, fmt);
  294.     sprintf(msg, fmt, err);
  295.     StopAlertMessage(msg);
  296.     return false;
  297.     
  298. exit2:
  299.  
  300.     StopAlertNumber(kStrNotAnApplication);
  301.     return false;
  302.     
  303. exit3:
  304.  
  305.     StopAlertNumber(kStrDesktopDatabaseDamaged);
  306.     return true;
  307.     
  308. exit4:
  309.  
  310.     CautionAlertNumber(kStrDuplicateCopiesOfHelper);
  311.     *fSpec = file;
  312.     return true;
  313. }
  314.  
  315.  
  316.  
  317. /*----------------------------------------------------------------------------
  318.     NewsreadingOptions
  319.  
  320.     Handle the newsreading options preferences dialog.
  321.     
  322.     Entry:    prefs = pointer to new prefs.
  323.             dlg = pointer to dialog.
  324.             item = item number hit.
  325. ----------------------------------------------------------------------------*/
  326.  
  327. static void NewsreadingOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  328. {
  329.     long maxFetch;
  330.  
  331.     switch (item) {
  332.     
  333.         case kInit:
  334.         
  335.             DlgSetCheck(dlg, kShowAuthors, prefs->showAuthors);
  336.             DlgSetCheck(dlg, kShowArtHeaders, prefs->showArtHeaders);
  337.             DlgSetCheck(dlg, kCollapseThreads, prefs->showThreadsCollapsed);
  338.             DlgSetCheck(dlg, kKeyboardShortcuts, prefs->keyboardShortcuts);
  339.             DlgSetCheck(dlg, kKeypadShortcuts, prefs->keypadShortcuts);
  340.             DlgSetCheck(dlg, kReuseArticleWinds, prefs->reuseArticleWinds);
  341.             DlgSetCheck(dlg, kReturnToSubjectWindow, prefs->returnToSubjectWindow);
  342.             DlgSetCheck(dlg, kBeepAtEndOfGroup, prefs->beepAtEndOfGroup);
  343.             DlgSetNumber(dlg, kMaxArticles, prefs->maxFetch);
  344.             SetItemNumeric(dlg, kMaxArticles);
  345.             SetItemMaxLength(dlg, kMaxArticles, 5);
  346.             SelectDialogItemText(dlg, kMaxArticles, 0, 0x7fff);
  347.             break;
  348.             
  349.         case kTerm:
  350.             
  351.             prefs->showAuthors = DlgGetCheck(dlg, kShowAuthors);
  352.             prefs->showArtHeaders = DlgGetCheck(dlg, kShowArtHeaders);
  353.             prefs->showThreadsCollapsed = DlgGetCheck(dlg, kCollapseThreads);
  354.             prefs->keyboardShortcuts = DlgGetCheck(dlg, kKeyboardShortcuts);
  355.             prefs->keypadShortcuts = DlgGetCheck(dlg, kKeypadShortcuts);
  356.             prefs->reuseArticleWinds = DlgGetCheck(dlg, kReuseArticleWinds);
  357.             prefs->returnToSubjectWindow = DlgGetCheck(dlg, kReturnToSubjectWindow);
  358.             prefs->beepAtEndOfGroup = DlgGetCheck(dlg, kBeepAtEndOfGroup);
  359.             maxFetch = DlgGetNumber(dlg, kMaxArticles);
  360.             if (maxFetch > 15000) maxFetch = 15000;
  361.             if (maxFetch <= 0) maxFetch = 1;
  362.             prefs->maxFetch = maxFetch;
  363.             break;
  364.             
  365.         case kShowAuthors:
  366.         case kShowArtHeaders:
  367.         case kCollapseThreads:
  368.         case kKeyboardShortcuts:
  369.         case kKeypadShortcuts:
  370.         case kReuseArticleWinds:
  371.         case kReturnToSubjectWindow:
  372.         case kBeepAtEndOfGroup:
  373.         
  374.             DlgToggleCheck(dlg, item);
  375.             break;
  376.             
  377.     }
  378. }
  379.  
  380.  
  381.  
  382. /*----------------------------------------------------------------------------
  383.     Server
  384.  
  385.     Handles the server info preferences dialog.
  386.     
  387.     Entry:    prefs = pointer to new prefs.
  388.             dlg = pointer to dialog.
  389.             item = item number hit.
  390. ----------------------------------------------------------------------------*/
  391.  
  392. static void Server (TPrefRec *prefs, DialogPtr dlg, short item)
  393. {
  394.     Boolean enable;
  395.  
  396.     switch (item) {
  397.     
  398.         case kInit:
  399.         
  400.             DlgSetPString(dlg, kNewsServer, prefs->newsServerName);
  401.             SetItemHostAddress(dlg, kNewsServer);
  402.             SetItemMaxLength(dlg, kNewsServer, 255);
  403.             DlgSetPString(dlg, kMailServer, prefs->mailServerName);
  404.             SetItemHostAddress(dlg, kMailServer);
  405.             SetItemMaxLength(dlg, kMailServer, 255);
  406.             if (*prefs->newsServerName == 0) {
  407.                 SelectDialogItemText(dlg, kNewsServer, 0, 0);
  408.             } else if (*prefs->mailServerName == 0) {
  409.                 SelectDialogItemText(dlg, kMailServer, 0, 0);
  410.             } else {
  411.                 SelectDialogItemText(dlg, kNewsServer, 0, 0x7fff);
  412.             }
  413.             break;
  414.             
  415.         case kTerm:
  416.             
  417.             break;
  418.             
  419.         case kNewsServer:
  420.         case kMailServer:
  421.         
  422.             DlgGetPString(dlg, kNewsServer, prefs->newsServerName);
  423.             DlgGetPString(dlg, kMailServer, prefs->mailServerName);
  424.             enable = *prefs->newsServerName != 0 && *prefs->mailServerName != 0;
  425.             DlgEnableItem(dlg, ok, enable);
  426.             DlgEnableItem(dlg, kTopicPopup, enable);
  427.             
  428.     }
  429. }
  430.  
  431.  
  432.  
  433. /*----------------------------------------------------------------------------
  434.     ServerOptions
  435.  
  436.     Handles the server options preferences dialog.
  437.     
  438.     Entry:    prefs = pointer to new prefs.
  439.             dlg = pointer to dialog.
  440.             item = item number hit.
  441. ----------------------------------------------------------------------------*/
  442.  
  443. static void ServerOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  444. {
  445.     switch (item) {
  446.     
  447.         case kInit:
  448.         
  449.             DlgSetCheck(dlg, kBatchedGroupCmds, prefs->batchedGroupCmds);
  450.             DlgSetCheck(dlg, kUseXPAT, prefs->useXPAT);
  451.             DlgSetCheck(dlg, kNoNewConnection, prefs->noNewConnection);
  452.             DlgSetCheck(dlg, kNoModeReader, prefs->noModeReader);
  453.             break;
  454.             
  455.         case kTerm:
  456.             
  457.             prefs->batchedGroupCmds = DlgGetCheck(dlg, kBatchedGroupCmds);
  458.             prefs->useXPAT = DlgGetCheck(dlg, kUseXPAT);
  459.             prefs->noNewConnection = DlgGetCheck(dlg, kNoNewConnection);
  460.             prefs->noModeReader = DlgGetCheck(dlg, kNoModeReader);
  461.             break;
  462.             
  463.         case kBatchedGroupCmds:
  464.         case kUseXPAT:
  465.         case kNoNewConnection:
  466.         case kNoModeReader:
  467.         
  468.             DlgToggleCheck(dlg, item);
  469.             break;
  470.             
  471.     }
  472. }
  473.  
  474.  
  475.  
  476. /*----------------------------------------------------------------------------
  477.     Personal
  478.  
  479.     Handles the personal info preferences dialog.
  480.     
  481.     Entry:    prefs = pointer to new prefs.
  482.             dlg = pointer to dialog.
  483.             item = item number hit.
  484. ----------------------------------------------------------------------------*/
  485.  
  486. static void Personal (TPrefRec *prefs, DialogPtr dlg, short item)
  487. {
  488.     switch (item) {
  489.     
  490.         case kInit:
  491.         
  492.             DlgSetCString(dlg, kFullName, prefs->fullName);
  493.             SetItemMaxLength(dlg, kFullName, 255);
  494.             DlgSetCString(dlg, kOrganization, prefs->organization);
  495.             SetItemMaxLength(dlg, kOrganization, 255);
  496.             DlgSetCString(dlg, kMailAddress, prefs->emailAddress);
  497.             SetItemUSAsciiNoBlank(dlg, kMailAddress);
  498.             SetItemMaxLength(dlg, kMailAddress, 255);
  499.             if (*prefs->fullName == 0) {
  500.                 SelectDialogItemText(dlg, kFullName, 0, 0);
  501.             } else if (*prefs->organization == 0) {
  502.                 SelectDialogItemText(dlg, kOrganization, 0, 0);
  503.             } else if (*prefs->emailAddress == 0) {
  504.                 SelectDialogItemText(dlg, kMailAddress, 0, 0);
  505.             } else {
  506.                 SelectDialogItemText(dlg, kFullName, 0, 0x7fff);
  507.             }
  508.             break;
  509.             
  510.         case kTerm:
  511.             
  512.             DlgGetCString(dlg, kFullName, prefs->fullName);
  513.             DlgGetCString(dlg, kOrganization, prefs->organization);
  514.             break;
  515.             
  516.         case kMailAddress:
  517.         
  518.             DlgGetCString(dlg, kMailAddress, prefs->emailAddress);
  519.             DlgEnableItem(dlg, ok, *prefs->emailAddress != 0);
  520.             DlgEnableItem(dlg, kTopicPopup, *prefs->emailAddress != 0);
  521.             
  522.     }
  523. }
  524.  
  525.  
  526.  
  527. /*----------------------------------------------------------------------------
  528.     Signature
  529.  
  530.     Handles the signature preferences dialog.
  531.     
  532.     Entry:    prefs = pointer to new prefs.
  533.             dlg = pointer to dialog.
  534.             item = item number hit.
  535. ----------------------------------------------------------------------------*/
  536.  
  537. static void Signature (TPrefRec *prefs, DialogPtr dlg, short item)
  538. {
  539.     short len;
  540.  
  541.     switch (item) {
  542.     
  543.         case kInit:
  544.         
  545.             DlgSetCheck(dlg, kAddSigBlankLine, prefs->addSigBlankLine);
  546.             DlgSetCheck(dlg, kAddSigSeparator, prefs->addSigSeparatorLine);
  547.             SetItemScrollingTextField(dlg, kSignatureEditText, 
  548.                 gPrefs.textFont, gPrefs.textSize, false);
  549.             DlgSetScrollingText(dlg, kSignatureEditText, prefs->signature,
  550.                 strlen(prefs->signature));
  551.             DlgSetScrollingTextSelection(dlg, kSignatureEditText, 0, 0);
  552.             SetItemMaxLength(dlg, kSignatureEditText, 4095);
  553.             break;
  554.             
  555.         case kTerm:
  556.             
  557.             prefs->addSigBlankLine = DlgGetCheck(dlg, kAddSigBlankLine);
  558.             prefs->addSigSeparatorLine = DlgGetCheck(dlg, kAddSigSeparator);
  559.             DlgGetScrollingText(dlg, kSignatureEditText, prefs->signature, &len);
  560.             prefs->signature[len] = 0;
  561.             break;
  562.             
  563.         case kAddSigBlankLine:
  564.         case kAddSigSeparator:
  565.         
  566.             DlgToggleCheck(dlg, item);
  567.             break;
  568.             
  569.     }
  570. }
  571.  
  572.  
  573.  
  574. /*----------------------------------------------------------------------------
  575.     MessageOptions
  576.  
  577.     Handles the message options preferences dialog.
  578.     
  579.     Entry:    prefs = pointer to new prefs.
  580.             dlg = pointer to dialog.
  581.             item = item number hit.
  582. ----------------------------------------------------------------------------*/
  583.  
  584. static void MessageOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  585. {
  586.  
  587.     switch (item) {
  588.     
  589.         case kInit:
  590.         
  591.             DlgSetCheck(dlg, kMsgReplyPost, prefs->replyPost);
  592.             DlgSetCheck(dlg, kMsgReplyEmail, prefs->replyEmail);
  593.             DlgSetCheck(dlg, kMsgCopySelf, prefs->copySelf);
  594.             DlgSetCheck(dlg, kMsgShowMsgDetails, prefs->showMsgDetails);
  595.             DlgSetCheck(dlg, kMsgWrapOnSend, prefs->wrapOnSend);
  596.             DlgSetCheck(dlg, kMsgTabEnabled, prefs->tabEnabled);
  597.             DlgSetNumber(dlg, kMsgTabStops, prefs->tabStops);
  598.             SetItemNumeric(dlg, kMsgTabStops);
  599.             SetItemMaxLength(dlg, kMsgTabStops, 2);
  600.             SelectDialogItemText(dlg, kMsgTabStops, 0, 0x7fff);
  601.             DlgSetCString(dlg, kMsgQuoteString, prefs->quoteString);
  602.             SetItemMaxLength(dlg, kMsgQuoteString, 10);
  603.             break;
  604.             
  605.         case kTerm:
  606.             
  607.             prefs->replyPost = DlgGetCheck(dlg, kMsgReplyPost);
  608.             prefs->replyEmail = DlgGetCheck(dlg, kMsgReplyEmail);
  609.             prefs->copySelf = DlgGetCheck(dlg, kMsgCopySelf);
  610.             prefs->showMsgDetails = DlgGetCheck(dlg, kMsgShowMsgDetails);
  611.             prefs->wrapOnSend = DlgGetCheck(dlg, kMsgWrapOnSend);
  612.             prefs->tabEnabled = DlgGetCheck(dlg, kMsgTabEnabled);
  613.             prefs->tabStops = DlgGetNumber(dlg, kMsgTabStops);
  614.             DlgGetCString(dlg, kMsgQuoteString, prefs->quoteString);
  615.               break;
  616.             
  617.         case kMsgReplyPost:
  618.         case kMsgReplyEmail:
  619.         case kMsgCopySelf:
  620.         case kMsgShowMsgDetails:
  621.         case kMsgWrapOnSend:
  622.         case kMsgTabEnabled:
  623.         
  624.             DlgToggleCheck(dlg, item);
  625.             break;
  626.             
  627.     }
  628. }
  629.  
  630.  
  631.  
  632. /*----------------------------------------------------------------------------
  633.     ExtraHeaderLines
  634.  
  635.     Handles the extra header lines preferences dialog.
  636.     
  637.     Entry:    prefs = pointer to new prefs.
  638.             dlg = pointer to dialog.
  639.             item = item number hit.
  640. ----------------------------------------------------------------------------*/
  641.  
  642. static void ExtraHeaderLines (TPrefRec *prefs, DialogPtr dlg, short item)
  643. {
  644.     short len;
  645.  
  646.     switch (item) {
  647.     
  648.         case kInit:
  649.         
  650.             SetItemScrollingTextField(dlg, kMsgExtraNewsHdrLines, 
  651.                 gPrefs.textFont, gPrefs.textSize, false);
  652.             DlgSetScrollingText(dlg, kMsgExtraNewsHdrLines, prefs->extraNewsHdrLines,
  653.                 strlen(prefs->extraNewsHdrLines));
  654.             SetItemMaxLength(dlg, kMsgExtraNewsHdrLines, 255);
  655.             SetItemScrollingTextField(dlg, kMsgExtraMailHdrLines, 
  656.                 gPrefs.textFont, gPrefs.textSize, false);
  657.             DlgSetScrollingText(dlg, kMsgExtraMailHdrLines, prefs->extraMailHdrLines,
  658.                 strlen(prefs->extraMailHdrLines));
  659.             SetItemMaxLength(dlg, kMsgExtraMailHdrLines, 255);
  660.             DlgSetScrollingTextSelection(dlg, kMsgExtraNewsHdrLines, 0, 0);
  661.             break;
  662.             
  663.         case kTerm:
  664.             
  665.             DlgGetScrollingText(dlg, kMsgExtraNewsHdrLines, prefs->extraNewsHdrLines, &len);
  666.             prefs->extraNewsHdrLines[len] = 0;
  667.             DlgGetScrollingText(dlg, kMsgExtraMailHdrLines, prefs->extraMailHdrLines, &len);
  668.             prefs->extraMailHdrLines[len] = 0;
  669.               break;
  670.             
  671.     }
  672. }
  673.  
  674.  
  675.  
  676. /*----------------------------------------------------------------------------
  677.     Remote
  678.  
  679.     Handles the remote host info preferences dialog.
  680.     
  681.     Entry:    prefs = pointer to new prefs.
  682.             dlg = pointer to dialog.
  683.             item = item number hit.
  684. ----------------------------------------------------------------------------*/
  685.  
  686. static void Remote (TPrefRec *prefs, DialogPtr dlg, short item)
  687. {
  688.     CStr255 tempStr;
  689.     short len;
  690.  
  691.     switch (item) {
  692.     
  693.         case kInit:
  694.         
  695.             DlgSetCString(dlg, kRemoteHostAddr, prefs->ftpNewsrcHost);
  696.             SetItemHostAddress(dlg, kRemoteHostAddr);
  697.             SetItemMaxLength(dlg, kRemoteHostAddr, 255);
  698.             DlgSetCString(dlg, kRemoteLogin, prefs->ftpNewsrcUsername);
  699.             SetItemMaxLength(dlg, kRemoteLogin, 255);
  700.             len = strlen(prefs->ftpNewsrcPassword);
  701.             memset(tempStr, '•', len);
  702.             tempStr[len] = 0;
  703.             DlgSetCString(dlg, kRemotePassword, tempStr);
  704.             SetItemPassword(dlg, kRemotePassword, prefs->ftpNewsrcPassword);
  705.             SetItemMaxLength(dlg, kRemotePassword, 31);
  706.             DlgSetCString(dlg, kRemotePath, prefs->ftpNewsrcPath);
  707.             SetItemMaxLength(dlg, kRemotePath, 31);
  708.             DlgSetCheck(dlg, kAutoGetPut, prefs->autoFetchNewsrc);
  709.             DlgSetCheck(dlg, kSavePassword, prefs->saveFtpNewsrcPassword);
  710.             if (*prefs->ftpNewsrcHost == 0) {
  711.                 SelectDialogItemText(dlg, kRemoteHostAddr, 0, 0);
  712.             } else if (*prefs->ftpNewsrcUsername == 0) {
  713.                 SelectDialogItemText(dlg, kRemoteLogin, 0, 0);
  714.             } else if (*prefs->ftpNewsrcPassword == 0) {
  715.                 SelectDialogItemText(dlg, kRemotePassword, 0, 0);
  716.             } else if (*prefs->ftpNewsrcPath == 0) {
  717.                 SelectDialogItemText(dlg, kRemotePath, 0, 0);
  718.             } else {
  719.                 SelectDialogItemText(dlg, kRemoteHostAddr, 0, 0x7fff);
  720.             }
  721.             break;
  722.             
  723.         case kTerm:
  724.             
  725.             DlgGetCString(dlg, kRemoteHostAddr, prefs->ftpNewsrcHost);
  726.             DlgGetCString(dlg, kRemoteLogin, prefs->ftpNewsrcUsername);
  727.             DlgGetCString(dlg, kRemotePath, prefs->ftpNewsrcPath);
  728.             prefs->autoFetchNewsrc = DlgGetCheck(dlg, kAutoGetPut);
  729.             prefs->saveFtpNewsrcPassword = DlgGetCheck(dlg, kSavePassword);
  730.             break;
  731.         
  732.         case kSavePassword:
  733.         case kAutoGetPut:
  734.         
  735.             DlgToggleCheck(dlg, item);
  736.             break;
  737.             
  738.     }
  739. }
  740.  
  741.  
  742.  
  743. /*----------------------------------------------------------------------------
  744.     DrawFontSample
  745.     
  746.     A user item procedure to draw the font samples.
  747.     
  748.     Entry:    dlg = pointer to dialog.
  749.             item = item number.
  750. ----------------------------------------------------------------------------*/
  751.  
  752. static pascal void DrawFontSample (DialogPtr dlg, short item)
  753. {
  754.     short itemType;
  755.     Rect box;
  756.     Handle itemHandle;
  757.     Str255 text;
  758.     short fontID, fontSize;
  759.     TextStyle savedStyle;
  760.  
  761.     DlgGrayBorderItem(dlg, item);
  762.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  763.     if (gScreenFontsTopic) {
  764.         if (item == kListSample) {
  765.             GetPString(kStrGroupSubjectSample, text);
  766.             fontID = gListFontID;
  767.             fontSize = gListFontSize;
  768.         } else {
  769.             GetPString(kStrArtMsgSample, text);
  770.             fontID = gTextFontID;
  771.             fontSize = gTextFontSize;
  772.         }
  773.     } else {
  774.         GetPString(kStrPrintingSample, text);
  775.         fontID = gPrintingFontID;
  776.         fontSize = gPrintingFontSize;
  777.     }
  778.     GetPortTextStyle(&savedStyle);
  779.     TextFont(fontID);
  780.     TextSize(fontSize);
  781.     InsetRect(&box, 2, 2);
  782.     TETextBox(text + 1, *text, &box, teFlushDefault);
  783.     SetPortTextStyle(&savedStyle);
  784. }
  785.  
  786.  
  787.  
  788. /*----------------------------------------------------------------------------
  789.     RedrawSample
  790.  
  791.     Force one of the sample text items to be redrawn.
  792.     
  793.     Entry:    dlg = pointer to dialog.
  794.             item = item number.
  795. ----------------------------------------------------------------------------*/
  796.  
  797. static void RedrawSample (DialogPtr dlg, short item)
  798. {
  799.     short itemType;
  800.     Handle itemHandle;
  801.     Rect box;
  802.     
  803.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  804.     InsetRect(&box, 2, 2);
  805.     EraseRect(&box);
  806.     InvalRect(&box);
  807. }
  808.  
  809.  
  810.  
  811. /*----------------------------------------------------------------------------
  812.     SetNewFont
  813.  
  814.     Set a new font in the font/size dialog.
  815.     
  816.     Entry:    dlg = pointer to dialog.
  817.             listFont = true if list font, false if text font.
  818.             fontNum = new font number.
  819. ----------------------------------------------------------------------------*/
  820.  
  821. static void SetNewFont (DialogPtr dlg, Boolean listFont, short fontNum)
  822. {
  823.     short numItems, i;
  824.     Str255 itemStr, fontName;
  825.     ControlHandle ctl;
  826.     long size;
  827.  
  828.     /* Select the right font in the font popup menu. */
  829.     
  830.     ctl = DlgGetControl(dlg, 
  831.         gScreenFontsTopic ? (listFont ? kListFontPopup : kTextFontPopup) : kPrintingFontPopup);
  832.     GetFontName(fontNum, fontName);
  833.     SetPopupValue(ctl, fontName, false);
  834.     
  835.     /* Adjust the size popup so the nice sizes are outlined. */
  836.  
  837.     ctl = DlgGetControl(dlg, 
  838.         gScreenFontsTopic ? (listFont ? kListSizePopup : kTextSizePopup) : kPrintingSizePopup);
  839.     numItems = GetControlMaximum(ctl);
  840.     for (i = 1; i <= numItems; i++) {
  841.         GetPopupPString(ctl, i, itemStr);
  842.         StringToNum(itemStr, &size);
  843.         if (RealFont(fontNum, (short)size)) {
  844.             SetPopupItemStyle(ctl, i, outline);
  845.         } else {
  846.             SetPopupItemStyle(ctl, i, 0);
  847.         }
  848.     }
  849.  
  850.     /* Force the sample text to be redrawn */
  851.     
  852.     RedrawSample(dlg, 
  853.         gScreenFontsTopic ? (listFont ? kListSample : kTextSample) : kPrintingSample);
  854. }
  855.  
  856.  
  857.  
  858. /*----------------------------------------------------------------------------
  859.     FontIDFromPopup
  860.  
  861.     Get the font ID corresponding the currently selected font in a popup menu.
  862.     
  863.     Entry:    dlg = pointer to dialog.
  864.             item = item number of popup menu.
  865. ----------------------------------------------------------------------------*/
  866.  
  867. static short FontIDFromPopup (DialogPtr dlg, short item)
  868. {
  869.     ControlHandle ctl;
  870.     short fontNum;
  871.     Str255 fontName;
  872.  
  873.     ctl = DlgGetControl(dlg, item);
  874.     GetPopupPString(ctl, kCurrentPopupItem, fontName);
  875.     GetFontNumber(fontName, &fontNum);
  876.     return fontNum;
  877. }
  878.  
  879.  
  880.  
  881. /*----------------------------------------------------------------------------
  882.     ScreenFonts
  883.  
  884.     Handles the screen fonts preferences dialog.
  885.     
  886.     Entry:    prefs = pointer to new prefs.
  887.             dlg = pointer to dialog.
  888.             item = item number hit.
  889. ----------------------------------------------------------------------------*/
  890.  
  891. static void ScreenFonts (TPrefRec *prefs, DialogPtr dlg, short item)
  892. {
  893.     Str255 tempStr;
  894.     long num;
  895.  
  896.     switch (item) {
  897.     
  898.         case kInit:
  899.         
  900.             gScreenFontsTopic = true;
  901.             GetFontNumber(prefs->listFont, &gListFontID);
  902.             gListFontSize = prefs->listSize;
  903.             SetNewFont(dlg, true, gListFontID);
  904.             DlgSetNumber(dlg, kListSizeBox, gListFontSize);
  905.             SetItemNumeric(dlg, kListSizeBox);
  906.             SetItemMaxLength(dlg, kListSizeBox, 2);
  907.             SelectDialogItemText(dlg, kListSizeBox, 0, 0x7fff);
  908.             SetItemPopupTypeinItem(dlg, kListSizePopup, kListSizeBox);
  909.             
  910.             GetFontNumber(prefs->textFont, &gTextFontID);
  911.             gTextFontSize = prefs->textSize;
  912.             SetNewFont(dlg, false, gTextFontID);
  913.             DlgSetNumber(dlg, kTextSizeBox, gTextFontSize);
  914.             SetItemNumeric(dlg, kTextSizeBox);
  915.             SetItemMaxLength(dlg, kTextSizeBox, 2);
  916.             SetItemPopupTypeinItem(dlg, kTextSizePopup, kTextSizeBox);
  917.             
  918.               DlgSetUserItem(dlg, kListSample, gDrawFontSampleUPP);
  919.               DlgSetUserItem(dlg, kTextSample, gDrawFontSampleUPP);
  920.               DlgSetUserItem(dlg, kListVertLine, gDlgGrayBorderItemUPP);
  921.             break;
  922.             
  923.         case kTerm:
  924.             
  925.               GetFontName(gListFontID, prefs->listFont);
  926.               GetFontName(gTextFontID, prefs->textFont);
  927.               prefs->listSize = gListFontSize;
  928.               prefs->textSize = gTextFontSize;
  929.             break;
  930.             
  931.         case kListFontPopup:
  932.         
  933.               gListFontID = FontIDFromPopup(dlg, item);
  934.               SetNewFont(dlg, true, gListFontID);
  935.             break;
  936.             
  937.         case kTextFontPopup:
  938.         
  939.               gTextFontID = FontIDFromPopup(dlg, item);
  940.               SetNewFont(dlg, false, gTextFontID);
  941.             break;            
  942.           
  943.         case kListSizePopup:
  944.         case kListSizeBox:
  945.         
  946.               DlgGetPString(dlg, kListSizeBox, tempStr);
  947.               StringToNum(tempStr, &num);
  948.               if (num != 0 && num != gListFontSize) {
  949.                   gListFontSize = num;
  950.                   RedrawSample(dlg, kListSample);
  951.               }
  952.             break;
  953.           
  954.         case kTextSizePopup:
  955.         case kTextSizeBox:
  956.         
  957.               DlgGetPString(dlg, kTextSizeBox, tempStr);
  958.               StringToNum(tempStr, &num);
  959.               if (num != 0 && num != gTextFontSize) {
  960.                   gTextFontSize = num;
  961.                   RedrawSample(dlg, kTextSample);
  962.               }
  963.             break;
  964.             
  965.     }
  966. }
  967.  
  968.  
  969.  
  970. /*----------------------------------------------------------------------------
  971.     PrintingFont
  972.  
  973.     Handles the printing font preferences dialog.
  974.     
  975.     Entry:    prefs = pointer to new prefs.
  976.             dlg = pointer to dialog.
  977.             item = item number hit.
  978. ----------------------------------------------------------------------------*/
  979.  
  980. static void PrintingFont (TPrefRec *prefs, DialogPtr dlg, short item)
  981. {
  982.     Str255 tempStr;
  983.     long num;
  984.  
  985.     switch (item) {
  986.     
  987.         case kInit:
  988.         
  989.             gScreenFontsTopic = false;
  990.             GetFontNumber(prefs->printingFont, &gPrintingFontID);
  991.             gPrintingFontSize = prefs->printingSize;
  992.             SetNewFont(dlg, true, gPrintingFontID);
  993.             DlgSetNumber(dlg, kPrintingSizeBox, gPrintingFontSize);
  994.             SetItemNumeric(dlg, kPrintingSizeBox);
  995.             SetItemMaxLength(dlg, kPrintingSizeBox, 2);
  996.             SelectDialogItemText(dlg, kPrintingSizeBox, 0, 0x7fff);
  997.             SetItemPopupTypeinItem(dlg, kPrintingSizePopup, kPrintingSizeBox);
  998.               DlgSetUserItem(dlg, kPrintingSample, gDrawFontSampleUPP);
  999.             break;
  1000.             
  1001.         case kTerm:
  1002.             
  1003.               GetFontName(gPrintingFontID, prefs->printingFont);
  1004.               prefs->printingSize = gPrintingFontSize;
  1005.             break;
  1006.             
  1007.         case kPrintingFontPopup:
  1008.         
  1009.               gPrintingFontID = FontIDFromPopup(dlg, item);
  1010.               SetNewFont(dlg, true, gPrintingFontID);
  1011.             break;
  1012.           
  1013.         case kPrintingSizePopup:
  1014.         case kPrintingSizeBox:
  1015.         
  1016.               DlgGetPString(dlg, kPrintingSizeBox, tempStr);
  1017.               StringToNum(tempStr, &num);
  1018.               if (num != 0 && num != gPrintingFontSize) {
  1019.                   gPrintingFontSize = num;
  1020.                   RedrawSample(dlg, kPrintingSample);
  1021.               }
  1022.             break;
  1023.             
  1024.     }
  1025. }
  1026.  
  1027.  
  1028.  
  1029. /*----------------------------------------------------------------------------
  1030.     SavedUGL
  1031.  
  1032.     Handles the saved user group lists preferences dialog.
  1033.     
  1034.     Entry:    prefs = pointer to new prefs.
  1035.             dlg = pointer to dialog.
  1036.             item = item number hit.
  1037. ----------------------------------------------------------------------------*/
  1038.  
  1039. static void SavedUGL (TPrefRec *prefs, DialogPtr dlg, short item)
  1040. {
  1041.     StandardFileReply reply;
  1042.     long dirID;
  1043.     Str31 name;
  1044.     OSErr err = noErr;
  1045.     CInfoPBRec pb;
  1046.     Boolean valid;
  1047.     AliasHandle alias;
  1048.  
  1049.     switch (item) {
  1050.     
  1051.         case kInit:
  1052.  
  1053.             DlgSetCheck(dlg, kSavedUGLDirCheckBox, prefs->savedUGLDefaultFolder);
  1054.               DlgSetUserItem(dlg, kSavedUGLDirBorder, gDlgGrayBorderItemUPP);            
  1055.             ValidateSavedFolderAlias(gPrefs.savedUGLDefaultFolderAlias,
  1056.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1057.               if (valid) {
  1058.                 pb.dirInfo.ioNamePtr = name;
  1059.                 pb.dirInfo.ioFDirIndex = -1;
  1060.                 err = PBGetCatInfo(&pb, false);
  1061.             } else {
  1062.                *name = 0;
  1063.             }
  1064.             DlgSetPString(dlg, kSavedUGLDirName, name);
  1065.             DlgEnableItem(dlg, kSavedUGLDirButton, prefs->savedUGLDefaultFolder);
  1066.             DlgSetCheck(dlg, kSavedUGLAutoSaveOnQuit, prefs->autoSaveOnQuit);
  1067.                 
  1068.             break;
  1069.             
  1070.         case kTerm:
  1071.         
  1072.             prefs->autoSaveOnQuit = DlgGetCheck(dlg, kSavedUGLAutoSaveOnQuit);
  1073.             break;
  1074.             
  1075.         case kSavedUGLDirCheckBox:
  1076.         
  1077.             DlgToggleCheck(dlg, item);
  1078.             prefs->savedUGLDefaultFolder = DlgGetCheck(dlg, item);
  1079.             DlgEnableItem(dlg, kSavedUGLDirButton, prefs->savedUGLDefaultFolder);
  1080.             break;
  1081.             
  1082.         case kSavedUGLDirButton:
  1083.         
  1084.             MyStandardGetDirectory(&reply, &dirID);
  1085.             if (!reply.sfGood) break;
  1086.             err = NewAlias(nil, &reply.sfFile, &alias);
  1087.             if (err == noErr) {
  1088.                 MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  1089.                 prefs->savedUGLDefaultFolderAlias = alias;
  1090.             }
  1091.             DlgSetPString(dlg, kSavedUGLDirName, reply.sfFile.name);
  1092.             break;
  1093.             
  1094.         case kSavedUGLAutoSaveOnQuit:
  1095.         
  1096.             DlgToggleCheck(dlg, item);
  1097.             break;
  1098.             
  1099.     }
  1100. }
  1101.  
  1102.  
  1103.  
  1104. /*----------------------------------------------------------------------------
  1105.     InvisibleFilesFilter
  1106.  
  1107.     A standard file dialog filter to filter out invisible files.
  1108.     
  1109.     Entry:    pb = pointer to file info param block.
  1110.             myDataPtr = pointer to private data (not used).
  1111.             
  1112.     Exit:    function result = true if file is invisible.
  1113. ----------------------------------------------------------------------------*/
  1114.  
  1115. static pascal Boolean InvisibleFilesFilter (CInfoPBPtr pb, void *myDataPtr)
  1116. {
  1117.     return (pb->hFileInfo.ioFlFndrInfo.fdFlags & fInvisible) != 0;
  1118. }
  1119.  
  1120.  
  1121.  
  1122. /*----------------------------------------------------------------------------
  1123.     SavedArt
  1124.  
  1125.     Handles the saved articles preferences dialog.
  1126.     
  1127.     Entry:    prefs = pointer to new prefs.
  1128.             dlg = pointer to dialog.
  1129.             item = item number hit.
  1130. ----------------------------------------------------------------------------*/
  1131.  
  1132. static void SavedArt (TPrefRec *prefs, DialogPtr dlg, short item)
  1133. {
  1134.     StandardFileReply reply;
  1135.     FInfo fInfo;
  1136.     long dirID;
  1137.     Str31 name;
  1138.     OSErr err = noErr;
  1139.     CInfoPBRec pb;
  1140.     Boolean valid;
  1141.     AliasHandle alias;
  1142.  
  1143.     switch (item) {
  1144.     
  1145.         case kInit:
  1146.  
  1147.               DlgSetUserItem(dlg, kSavedArtAppBorder, gDlgGrayBorderItemUPP);
  1148.               err = FindAppNameFromSig(prefs->savedArtCreator, name);
  1149.               if (err == noErr) {
  1150.                   DlgSetPString(dlg, kSavedArtAppName, name);
  1151.                   CopyPascalString(prefs->savedArtAppName, name);
  1152.               } else {
  1153.                 DlgSetPString(dlg, kSavedArtAppName, prefs->savedArtAppName);
  1154.             }
  1155.             DlgSetCheck(dlg, kSavedArtDirCheckBox, prefs->savedArtDefaultFolder);
  1156.               DlgSetUserItem(dlg, kSavedArtDirBorder, gDlgGrayBorderItemUPP);            
  1157.             ValidateSavedFolderAlias(gPrefs.savedArtDefaultFolderAlias,
  1158.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1159.               if (valid) {
  1160.                 pb.dirInfo.ioNamePtr = name;
  1161.                 pb.dirInfo.ioFDirIndex = -1;
  1162.                 err = PBGetCatInfo(&pb, false);
  1163.             } else {
  1164.                *name = 0;
  1165.             }
  1166.             DlgSetPString(dlg, kSavedArtDirName, name);
  1167.             DlgEnableItem(dlg, kSavedArtDirButton, prefs->savedArtDefaultFolder);
  1168.             DlgSetCheck(dlg, kSavedArtSepFiles, prefs->saveThreadsToSeparateFiles);
  1169.             DlgSetCheck(dlg, kSavedArtAutoAppend, prefs->appendIfFileAlreadyExists);
  1170.             DlgSetCheck(dlg, kSavedArtSaveEncoded, prefs->saveEncodedText);
  1171.                 
  1172.             break;
  1173.             
  1174.         case kTerm:
  1175.         
  1176.             prefs->saveThreadsToSeparateFiles = DlgGetCheck(dlg, kSavedArtSepFiles);
  1177.             prefs->appendIfFileAlreadyExists = DlgGetCheck(dlg, kSavedArtAutoAppend);
  1178.             prefs->saveEncodedText = DlgGetCheck(dlg, kSavedArtSaveEncoded);
  1179.             break;
  1180.             
  1181.         case kSavedArtAppButton:
  1182.         
  1183.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1184.             if (!reply.sfGood) break;
  1185.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1186.             prefs->savedArtCreator = fInfo.fdCreator;
  1187.             CopyPascalString(prefs->savedArtAppName, reply.sfFile.name);
  1188.             DlgSetPString(dlg, kSavedArtAppName, prefs->savedArtAppName);
  1189.             break;
  1190.             
  1191.         case kSavedArtDirCheckBox:
  1192.         
  1193.             DlgToggleCheck(dlg, item);
  1194.             prefs->savedArtDefaultFolder = DlgGetCheck(dlg, item);
  1195.             DlgEnableItem(dlg, kSavedArtDirButton, prefs->savedArtDefaultFolder);
  1196.             break;
  1197.             
  1198.         case kSavedArtDirButton:
  1199.         
  1200.             MyStandardGetDirectory(&reply, &dirID);
  1201.             if (!reply.sfGood) break;
  1202.             err = NewAlias(nil, &reply.sfFile, &alias);
  1203.             if (err == noErr) {
  1204.                 MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  1205.                 prefs->savedArtDefaultFolderAlias = alias;
  1206.             }
  1207.             DlgSetPString(dlg, kSavedArtDirName, reply.sfFile.name);
  1208.             break;
  1209.             
  1210.         case kSavedArtSepFiles:
  1211.         case kSavedArtAutoAppend:
  1212.         case kSavedArtSaveEncoded:
  1213.         
  1214.             DlgToggleCheck(dlg, item);
  1215.             break;
  1216.             
  1217.     }
  1218. }
  1219.  
  1220.  
  1221.  
  1222. /*----------------------------------------------------------------------------
  1223.     SavedMsg
  1224.  
  1225.     Handles the saved messages preferences dialog.
  1226.     
  1227.     Entry:    prefs = pointer to new prefs.
  1228.             dlg = pointer to dialog.
  1229.             item = item number hit.
  1230. ----------------------------------------------------------------------------*/
  1231.  
  1232. static void SavedMsg (TPrefRec *prefs, DialogPtr dlg, short item)
  1233. {
  1234.     StandardFileReply reply;
  1235.     long dirID;
  1236.     Str31 name;
  1237.     OSErr err = noErr;
  1238.     CInfoPBRec pb;
  1239.     Boolean valid;
  1240.     AliasHandle alias;
  1241.  
  1242.     switch (item) {
  1243.     
  1244.         case kInit:
  1245.  
  1246.             DlgSetCheck(dlg, kSavedMsgDirCheckBox, prefs->savedMsgDefaultFolder);
  1247.               DlgSetUserItem(dlg, kSavedMsgDirBorder, gDlgGrayBorderItemUPP);            
  1248.             ValidateSavedFolderAlias(prefs->savedMsgDefaultFolderAlias,
  1249.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1250.               if (valid) {
  1251.                 pb.dirInfo.ioNamePtr = name;
  1252.                 pb.dirInfo.ioFDirIndex = -1;
  1253.                 err = PBGetCatInfo(&pb, false);
  1254.             } else {
  1255.                 *name = 0;
  1256.             }
  1257.             DlgSetPString(dlg, kSavedMsgDirName, name);
  1258.             DlgEnableItem(dlg, kSavedMsgDirButton, prefs->savedMsgDefaultFolder);
  1259.             DlgSetCheck(dlg, kSavedMsgDelAfterSend, prefs->savedMsgDelAfterSend);
  1260.                 
  1261.             break;
  1262.             
  1263.         case kTerm:
  1264.         
  1265.             break;
  1266.             
  1267.         case kSavedMsgDirCheckBox:
  1268.         
  1269.             DlgToggleCheck(dlg, item);
  1270.             prefs->savedMsgDefaultFolder = DlgGetCheck(dlg, item);
  1271.             DlgEnableItem(dlg, kSavedMsgDirButton, prefs->savedMsgDefaultFolder);
  1272.             break;
  1273.             
  1274.         case kSavedMsgDirButton:
  1275.         
  1276.             MyStandardGetDirectory(&reply, &dirID);
  1277.             if (!reply.sfGood) break;
  1278.             err = NewAlias(nil, &reply.sfFile, &alias);
  1279.             if (err == noErr) {
  1280.                 MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  1281.                 prefs->savedMsgDefaultFolderAlias = alias;
  1282.             }
  1283.             DlgSetPString(dlg, kSavedMsgDirName, reply.sfFile.name);
  1284.             break;
  1285.             
  1286.         case kSavedMsgDelAfterSend:
  1287.         
  1288.             DlgToggleCheck(dlg, item);
  1289.             prefs->savedMsgDelAfterSend = DlgGetCheck(dlg, item);
  1290.             break;
  1291.             
  1292.     }
  1293. }
  1294.  
  1295.  
  1296.  
  1297. /*----------------------------------------------------------------------------
  1298.     InitURLHelperField
  1299.  
  1300.     Initialize a URL helper field.
  1301.     
  1302.     Entry:    dlg = pointer to dialog.
  1303.             borderItem = item number of gray border.
  1304.             appNameItem = item number of application name.
  1305.             info = pointer to prefs URL helper info.
  1306. ----------------------------------------------------------------------------*/
  1307.  
  1308. static void InitURLHelperField (DialogPtr dlg, short borderItem, 
  1309.     short appNameItem, TURLHelperInfoPtr info)
  1310. {
  1311.     OSErr err = noErr;
  1312.     Str31 name;
  1313.  
  1314.     DlgSetUserItem(dlg, borderItem, gDlgGrayBorderItemUPP);
  1315.     err = FindAppNameFromSig(info->sig, name);
  1316.     if (err != noErr) {
  1317.         info->sig = 0;
  1318.         *name = 0;
  1319.     }
  1320.     DlgSetPString(dlg, appNameItem, name);
  1321. }
  1322.  
  1323.  
  1324.  
  1325. /*----------------------------------------------------------------------------
  1326.     SetNewURLHelper
  1327.  
  1328.     Set a new URL helper.
  1329.     
  1330.     Entry:    dlg = pointer to dialog.
  1331.             appNameItem = item number of application name.
  1332.             info = pointer to prefs URL helper info.
  1333. ----------------------------------------------------------------------------*/
  1334.  
  1335. static void SetNewURLHelper (DialogPtr dlg, short appNameItem,
  1336.     TURLHelperInfoPtr info)
  1337. {
  1338.     StandardFileReply reply;
  1339.  
  1340.     MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1341.     if (!reply.sfGood) return;
  1342.     
  1343.     if (!ValidHelper(&reply.sfFile)) return;
  1344.     
  1345.     if (ValidURLHelper(&reply.sfFile, info))
  1346.         DlgSetPString(dlg, appNameItem, reply.sfFile.name);
  1347. }
  1348.  
  1349.  
  1350.  
  1351. /*----------------------------------------------------------------------------
  1352.     URLHelpers1
  1353.  
  1354.     Handles the URL helper programs 1 preferences dialog.
  1355.     
  1356.     Entry:    prefs = pointer to new prefs.
  1357.             dlg = pointer to dialog.
  1358.             item = item number hit.
  1359. ----------------------------------------------------------------------------*/
  1360.  
  1361. static void URLHelpers1 (TPrefRec *prefs, DialogPtr dlg, short item)
  1362. {
  1363.     switch (item) {
  1364.     
  1365.         case kInit:
  1366.         
  1367.             InitURLHelperField(dlg, kFTPAppBorder, kFTPAppName,
  1368.                 &prefs->ftpHelperInfo);
  1369.             InitURLHelperField(dlg, kHTTPAppBorder, kHTTPAppName,
  1370.                 &prefs->httpHelperInfo);
  1371.             InitURLHelperField(dlg, kGopherAppBorder, kGopherAppName,
  1372.                 &prefs->gopherHelperInfo);
  1373.             InitURLHelperField(dlg, kWAISAppBorder, kWAISAppName,
  1374.                 &prefs->waisHelperInfo);
  1375.             break;
  1376.             
  1377.         case kTerm:
  1378.         
  1379.             break;
  1380.             
  1381.         case kFTPAppButton:
  1382.         
  1383.             SetNewURLHelper(dlg, kFTPAppName, &prefs->ftpHelperInfo);
  1384.             break;
  1385.             
  1386.         case kHTTPAppButton:
  1387.         
  1388.             SetNewURLHelper(dlg, kHTTPAppName, &prefs->httpHelperInfo);
  1389.             break;
  1390.             
  1391.         case kGopherAppButton:
  1392.         
  1393.             SetNewURLHelper(dlg, kGopherAppName, &prefs->gopherHelperInfo);
  1394.             break;            
  1395.             
  1396.         case kWAISAppButton:
  1397.         
  1398.             SetNewURLHelper(dlg, kWAISAppName, &prefs->waisHelperInfo);
  1399.             break;
  1400.     }
  1401. }
  1402.  
  1403.  
  1404.  
  1405. /*----------------------------------------------------------------------------
  1406.     URLHelpers2
  1407.  
  1408.     Handles the URL helper programs 2 preferences dialog.
  1409.     
  1410.     Entry:    prefs = pointer to new prefs.
  1411.             dlg = pointer to dialog.
  1412.             item = item number hit.
  1413. ----------------------------------------------------------------------------*/
  1414.  
  1415. static void URLHelpers2 (TPrefRec *prefs, DialogPtr dlg, short item)
  1416. {
  1417.     switch (item) {
  1418.     
  1419.         case kInit:
  1420.  
  1421.             InitURLHelperField(dlg, kTelnetAppBorder, kTelnetAppName,
  1422.                 &prefs->telnetHelperInfo);
  1423.             InitURLHelperField(dlg, ktn3270AppBorder, ktn3270AppName,
  1424.                 &prefs->tn3270HelperInfo);
  1425.             InitURLHelperField(dlg, kFingerAppBorder, kFingerAppName,
  1426.                 &prefs->fingerHelperInfo);
  1427.             InitURLHelperField(dlg, kWhoisAppBorder, kWhoisAppName,
  1428.                 &prefs->whoisHelperInfo);
  1429.             break;
  1430.             
  1431.         case kTerm:
  1432.         
  1433.             break;
  1434.             
  1435.         case kTelnetAppButton:
  1436.         
  1437.             SetNewURLHelper(dlg, kTelnetAppName, &prefs->telnetHelperInfo);
  1438.             break;
  1439.             
  1440.         case ktn3270AppButton:
  1441.         
  1442.             SetNewURLHelper(dlg, ktn3270AppName, &prefs->tn3270HelperInfo);
  1443.             break;            
  1444.             
  1445.         case kFingerAppButton:
  1446.         
  1447.             SetNewURLHelper(dlg, kFingerAppName, &prefs->fingerHelperInfo);
  1448.             break;
  1449.             
  1450.         case kWhoisAppButton:
  1451.         
  1452.             SetNewURLHelper(dlg, kWhoisAppName, &prefs->whoisHelperInfo);
  1453.             break;            
  1454.     }
  1455. }
  1456.  
  1457.  
  1458.  
  1459. /*----------------------------------------------------------------------------
  1460.     Auth
  1461.  
  1462.     Handles the authorization preferences dialog.
  1463.     
  1464.     Entry:    prefs = pointer to new prefs.
  1465.             dlg = pointer to dialog.
  1466.             item = item number hit.
  1467. ----------------------------------------------------------------------------*/
  1468.  
  1469. static void Auth (TPrefRec *prefs, DialogPtr dlg, short item)
  1470. {
  1471.     CStr255 tempStr;
  1472.     short len;
  1473.  
  1474.     switch (item) {
  1475.     
  1476.         case kInit:
  1477.  
  1478.             DlgSetCString(dlg, kAuthUsername, prefs->authUsername);
  1479.             SetItemUSAsciiNoBlank(dlg, kAuthUsername);
  1480.             SetItemMaxLength(dlg, kAuthUsername, 31);
  1481.             len = strlen(prefs->authPassword);
  1482.             memset(tempStr, '•', len);
  1483.             tempStr[len] = 0;
  1484.             DlgSetCString(dlg, kAuthPassword, tempStr);
  1485.             SetItemPassword(dlg, kAuthPassword, prefs->authPassword);
  1486.             SetItemMaxLength(dlg, kAuthPassword, 31);
  1487.             DlgSetCheck(dlg, kAuthSavePassword, prefs->authSavePassword);
  1488.             DlgSetCheck(dlg, kAuthPrivateGroups, prefs->authPrivateGroups);
  1489.             DlgSetCtlValue(dlg, prefs->authAtStartup ? kAuthAtStartup : 
  1490.                 kAuthWhenRequested, 1);
  1491.             if (*prefs->authUsername == 0) {
  1492.                 SelectDialogItemText(dlg, kAuthUsername, 0, 0);
  1493.             } else if (*prefs->authPassword == 0) {
  1494.                 SelectDialogItemText(dlg, kAuthPassword, 0, 0);
  1495.             } else {
  1496.                 SelectDialogItemText(dlg, kAuthUsername, 0, 0x7fff);
  1497.             }
  1498.             break;
  1499.             
  1500.         case kTerm:
  1501.             
  1502.             DlgGetCString(dlg, kAuthUsername, prefs->authUsername);
  1503.             prefs->authSavePassword = DlgGetCheck(dlg, kAuthSavePassword);
  1504.             prefs->authPrivateGroups = DlgGetCheck(dlg, kAuthPrivateGroups);
  1505.             prefs->authAtStartup = DlgGetCtlValue(dlg, kAuthAtStartup) == 1;
  1506.             break;
  1507.         
  1508.         case kAuthSavePassword:
  1509.         case kAuthPrivateGroups:
  1510.         
  1511.             DlgToggleCheck(dlg, item);
  1512.             break;
  1513.         
  1514.         case kAuthAtStartup:
  1515.         
  1516.             if (DlgGetCtlValue(dlg, kAuthAtStartup) == 0) {
  1517.                 DlgSetCtlValue(dlg, kAuthAtStartup, 1);
  1518.                 DlgSetCtlValue(dlg, kAuthWhenRequested, 0);
  1519.             }
  1520.             break;
  1521.             
  1522.         case kAuthWhenRequested:
  1523.         
  1524.             if (DlgGetCtlValue(dlg, kAuthWhenRequested) == 0) {
  1525.                 DlgSetCtlValue(dlg, kAuthWhenRequested, 1);
  1526.                 DlgSetCtlValue(dlg, kAuthAtStartup, 0);
  1527.             }
  1528.             break;
  1529.             
  1530.     }
  1531. }
  1532.  
  1533.  
  1534.  
  1535. /*----------------------------------------------------------------------------
  1536.     Extract
  1537.  
  1538.     Handles the extracting binaries preferences dialog.
  1539.     
  1540.     Entry:    prefs = pointer to new prefs.
  1541.             dlg = pointer to dialog.
  1542.             item = item number hit.
  1543. ----------------------------------------------------------------------------*/
  1544.  
  1545. static void Extract (TPrefRec *prefs, DialogPtr dlg, short item)
  1546. {
  1547.     StandardFileReply reply;
  1548.     FInfo fInfo;
  1549.     long dirID;
  1550.     Str31 name;
  1551.     OSErr err = noErr;
  1552.     CInfoPBRec pb;
  1553.     Boolean valid;
  1554.     AliasHandle alias;
  1555.  
  1556.     switch (item) {
  1557.     
  1558.         case kInit:
  1559.  
  1560.             DlgSetCheck(dlg, kSavedBinDirCheckBox, prefs->savedBinDefaultFolder);
  1561.               DlgSetUserItem(dlg, kSavedBinDirBorder, gDlgGrayBorderItemUPP);            
  1562.             ValidateSavedFolderAlias(prefs->savedBinDefaultFolderAlias,
  1563.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1564.               if (valid) {
  1565.                 pb.dirInfo.ioNamePtr = name;
  1566.                 pb.dirInfo.ioFDirIndex = -1;
  1567.                 err = PBGetCatInfo(&pb, false);
  1568.             } else {
  1569.                 *name = 0;
  1570.             }
  1571.             DlgSetPString(dlg, kSavedBinDirName, name);
  1572.             DlgEnableItem(dlg, kSavedBinDirButton, prefs->savedBinDefaultFolder);
  1573.             
  1574.               DlgSetUserItem(dlg, kHqxAppBorder, gDlgGrayBorderItemUPP);
  1575.               err = FindAppNameFromSig(prefs->hqxHelper, name);
  1576.               if (err == noErr) {
  1577.                   DlgSetPString(dlg, kHqxAppName, name);
  1578.                   CopyPascalString(prefs->hqxHelperName, name);
  1579.               } else {
  1580.                 DlgSetPString(dlg, kHqxAppName, prefs->hqxHelperName);
  1581.             }
  1582.             
  1583.               DlgSetUserItem(dlg, kUUAppBorder, gDlgGrayBorderItemUPP);
  1584.               err = FindAppNameFromSig(prefs->uuHelper, name);
  1585.               if (err == noErr) {
  1586.                   DlgSetPString(dlg, kUUAppName, name);
  1587.                   CopyPascalString(prefs->uuHelperName, name);
  1588.               } else {
  1589.                 DlgSetPString(dlg, kUUAppName, prefs->uuHelperName);
  1590.             }
  1591.                 
  1592.             break;
  1593.             
  1594.         case kTerm:
  1595.         
  1596.             break;
  1597.             
  1598.         case kSavedBinDirCheckBox:
  1599.         
  1600.             DlgToggleCheck(dlg, item);
  1601.             prefs->savedBinDefaultFolder = DlgGetCheck(dlg, item);
  1602.             DlgEnableItem(dlg, kSavedBinDirButton, prefs->savedBinDefaultFolder);
  1603.             break;
  1604.             
  1605.         case kSavedBinDirButton:
  1606.         
  1607.             MyStandardGetDirectory(&reply, &dirID);
  1608.             if (!reply.sfGood) break;
  1609.             err = NewAlias(nil, &reply.sfFile, &alias);
  1610.             if (err == noErr) {
  1611.                 MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  1612.                 prefs->savedBinDefaultFolderAlias = alias;
  1613.             }
  1614.             DlgSetPString(dlg, kSavedBinDirName, reply.sfFile.name);
  1615.             break;
  1616.             
  1617.         case kHqxAppButton:
  1618.         
  1619.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1620.             if (!reply.sfGood) break;
  1621.             if (!ValidHelper(&reply.sfFile)) break;
  1622.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1623.             prefs->hqxHelper = fInfo.fdCreator;
  1624.             CopyPascalString(prefs->hqxHelperName, reply.sfFile.name);
  1625.             DlgSetPString(dlg, kHqxAppName, prefs->hqxHelperName);
  1626.             break;            
  1627.             
  1628.         case kUUAppButton:
  1629.         
  1630.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1631.             if (!reply.sfGood) break;
  1632.             if (!ValidHelper(&reply.sfFile)) break;
  1633.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1634.             prefs->uuHelper = fInfo.fdCreator;
  1635.             CopyPascalString(prefs->uuHelperName, reply.sfFile.name);
  1636.             DlgSetPString(dlg, kUUAppName, prefs->uuHelperName);
  1637.             break;            
  1638.             
  1639.     }
  1640. }
  1641.  
  1642.  
  1643.  
  1644. /*----------------------------------------------------------------------------
  1645.     MiscOptions
  1646.  
  1647.     Handle the miscellaneous options preferences dialog.
  1648.     
  1649.     Entry:    prefs = pointer to new prefs.
  1650.             dlg = pointer to dialog.
  1651.             item = item number hit.
  1652. ----------------------------------------------------------------------------*/
  1653.  
  1654. static void MiscOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  1655. {
  1656.     switch (item) {
  1657.     
  1658.         case kInit:
  1659.         
  1660.             DlgSetCheck(dlg, kReZoomWindows, prefs->reZoomWindows);
  1661.             DlgSetCheck(dlg, kCheckNewGroups, prefs->checkForNewGroups);
  1662.             DlgSetCheck(dlg, kAreYouSure, prefs->areYouSureAlert);
  1663.             DlgSetCheck(dlg, kLogActionsToFile, prefs->logActionsToFile);
  1664.             DlgSetCheck(dlg, kDontCoverFinderIcons, prefs->dontCoverFinderIcons);
  1665.             DlgSetCheck(dlg, kUseInternetConfig, prefs->useInternetConfig);
  1666.             break;
  1667.             
  1668.         case kTerm:
  1669.             
  1670.             prefs->reZoomWindows = DlgGetCheck(dlg, kReZoomWindows);
  1671.             prefs->checkForNewGroups = DlgGetCheck(dlg, kCheckNewGroups);
  1672.             prefs->areYouSureAlert = DlgGetCheck(dlg, kAreYouSure);
  1673.             prefs->logActionsToFile = DlgGetCheck(dlg, kLogActionsToFile);
  1674.             prefs->dontCoverFinderIcons = DlgGetCheck(dlg, kDontCoverFinderIcons);
  1675.             prefs->useInternetConfig = DlgGetCheck(dlg, kUseInternetConfig);
  1676.             break;
  1677.             
  1678.         case kReZoomWindows:
  1679.         case kCheckNewGroups:
  1680.         case kAreYouSure:
  1681.         case kLogActionsToFile:
  1682.         case kDontCoverFinderIcons:
  1683.         case kUseInternetConfig:
  1684.         
  1685.             DlgToggleCheck(dlg, item);
  1686.             break;
  1687.             
  1688.     }
  1689. }
  1690.  
  1691.  
  1692.  
  1693. /*----------------------------------------------------------------------------
  1694.     DrawGrayOutline
  1695.  
  1696.     A user item procedure to draw the gray outline.
  1697.     
  1698.     Entry:    dlg = pointer to dialog.
  1699.             item = item number of gray outline user item.
  1700. ----------------------------------------------------------------------------*/
  1701.  
  1702. static pascal void DrawGrayOutline (DialogPtr dlg, short item)
  1703. {
  1704.     Handle itemHandle;
  1705.     ControlHandle popupCtl;
  1706.     short itemType;
  1707.     Rect box, popupBox, r;
  1708.  
  1709.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  1710.     GetDialogItem(dlg, kTopicPopup, &itemType, (Handle*)&popupCtl, &popupBox);
  1711.     popupBox = (**popupCtl).contrlRect;
  1712.     r = box;
  1713.     r.bottom = r.top + 1;
  1714.     r.right = popupBox.left - 1;
  1715.     DrawGrayRect(&r);
  1716.     r = box;
  1717.     r.bottom = r.top + 1;
  1718.     r.left = popupBox.right + 5;
  1719.     DrawGrayRect(&r);
  1720.     r = box;
  1721.     r.right = r.left + 1;
  1722.     DrawGrayRect(&r);
  1723.     r = box;
  1724.     r.left = r.right - 1;
  1725.     DrawGrayRect(&r);
  1726.     r = box;
  1727.     r.top = r.bottom - 1;
  1728.     DrawGrayRect(&r);
  1729. }
  1730.  
  1731.  
  1732.  
  1733. /*----------------------------------------------------------------------------
  1734.     DoPreferences
  1735.  
  1736.     Presents the Preferences dialog.
  1737.     
  1738.     Exit:    function result = error code.
  1739. ----------------------------------------------------------------------------*/
  1740.  
  1741. OSErr DoPreferences (void)
  1742. {
  1743.     typedef void (*prefsFuncPtr) (TPrefRec *prefs, DialogPtr dlg, short item);
  1744.     
  1745.     static prefsFuncPtr prefsFuncPtrs[] = {
  1746.         NewsreadingOptions,
  1747.         Server,
  1748.         ServerOptions,
  1749.         Personal,
  1750.         Signature,
  1751.         MessageOptions,
  1752.         ExtraHeaderLines,
  1753.         Remote,
  1754.         ScreenFonts,
  1755.         PrintingFont,
  1756.         SavedUGL,
  1757.         SavedArt,
  1758.         SavedMsg,
  1759.         URLHelpers1,
  1760.         URLHelpers2,
  1761.         Auth,
  1762.         Extract,
  1763.         MiscOptions,
  1764.     };
  1765.  
  1766.     static short curTopic = kNewsreadingOptions;
  1767.     
  1768.     short newTopic;
  1769.     prefsFuncPtr theFunc;
  1770.     TPrefRec *prefs = nil;
  1771.     DialogPtr dlg = nil;
  1772.     short item;
  1773.     Boolean reauthenticate = false;
  1774.     Handle theDITL;
  1775.     Point newLocn;
  1776.     OSErr err = noErr;
  1777.     GrafPtr port;
  1778.     
  1779.     GetPort(&port);
  1780.     
  1781.     MyICReadSharedPrefs(kICAllSharedPrefs);
  1782.     err = MyNewPtr(sizeof(TPrefRec), &prefs);
  1783.     if (err != noErr) goto exit;
  1784.     *prefs = gPrefs;
  1785.     if (prefs->savedMsgDefaultFolderAlias != nil) {
  1786.         err = MyHandToHand(&prefs->savedMsgDefaultFolderAlias);
  1787.         if (err != noErr) {
  1788.             prefs->savedMsgDefaultFolderAlias = nil;
  1789.             prefs->savedArtDefaultFolderAlias = nil;
  1790.             prefs->savedBinDefaultFolderAlias = nil;
  1791.             prefs->savedUGLDefaultFolderAlias = nil;
  1792.             goto exit;
  1793.         }
  1794.     }
  1795.     if (prefs->savedArtDefaultFolderAlias != nil) {
  1796.         err = MyHandToHand(&prefs->savedArtDefaultFolderAlias);
  1797.         if (err != noErr) {
  1798.             prefs->savedArtDefaultFolderAlias = nil;
  1799.             prefs->savedBinDefaultFolderAlias = nil;
  1800.             prefs->savedUGLDefaultFolderAlias = nil;
  1801.             goto exit;
  1802.         }
  1803.     }
  1804.     if (prefs->savedBinDefaultFolderAlias != nil) {
  1805.         err = MyHandToHand(&prefs->savedBinDefaultFolderAlias);
  1806.         if (err != noErr) {
  1807.             prefs->savedBinDefaultFolderAlias = nil;
  1808.             prefs->savedUGLDefaultFolderAlias = nil;
  1809.             goto exit;
  1810.         }
  1811.     }
  1812.     if (prefs->savedUGLDefaultFolderAlias != nil) {
  1813.         err = MyHandToHand(&prefs->savedUGLDefaultFolderAlias);
  1814.         if (err != noErr) {
  1815.             prefs->savedUGLDefaultFolderAlias = nil;
  1816.             goto exit;
  1817.         }
  1818.     }
  1819.  
  1820.     err = MyGetNewDialog(kPrefsDlg, ok, cancel, &dlg);
  1821.     if (err != noErr) goto exit;
  1822.     SetPort(dlg);
  1823.     RestoreMovableModalDialogPosition(dlg, gPrefs.prefsLoc);
  1824.     
  1825.     for (item = kFirstGrayLine; item <= kLastGrayLine; item++)
  1826.         DlgSetUserItem(dlg, item, gDlgGrayBorderItemUPP);
  1827.     if (curTopic == kScreenFonts || curTopic == kPrintingFont) SetCursor(&gWatchCurs);
  1828.     err = MyGetResource('DITL', kPrefsDlg + curTopic, &theDITL);
  1829.     if (err == noErr) err = MyAppendDITL(dlg, theDITL, overlayDITL);
  1830.     InitCursor();
  1831.     if (err != noErr) goto exit;
  1832.     MyReleaseResource(theDITL);
  1833.     DlgSetCtlValue(dlg, kTopicPopup, curTopic);
  1834.     theFunc = prefsFuncPtrs[curTopic - 1];
  1835.     (*theFunc)(prefs, dlg, kInit);
  1836.     DlgSetDefaultButtonOutline(dlg, curTopic != kSignature && curTopic != kExtraHeaderLines);
  1837.     
  1838.     while (true) {
  1839.         MyMovableModalDialog(dlg, DialogFilter, &item);
  1840.         if (item == ok || item == cancel) {
  1841.             (*theFunc)(prefs, dlg, kTerm);
  1842.             break;
  1843.         } else if (item == kTopicPopup) {
  1844.             newTopic = DlgGetCtlValue(dlg, kTopicPopup);
  1845.             if (newTopic != curTopic) {
  1846.                 (*theFunc)(prefs, dlg, kTerm);
  1847.                 curTopic = newTopic;
  1848.                 MyShortenDITL(dlg, CountDITL(dlg) - kCommonItems);
  1849.                 if (curTopic == kScreenFonts || curTopic == kPrintingFont) SetCursor(&gWatchCurs);
  1850.                 err = MyGetResource('DITL', kPrefsDlg + curTopic, &theDITL);
  1851.                 if (err == noErr) err = MyAppendDITL(dlg, theDITL, overlayDITL);
  1852.                 InitCursor();
  1853.                 if (err != noErr) goto exit;
  1854.                 MyReleaseResource(theDITL);
  1855.                 theFunc = prefsFuncPtrs[curTopic - 1];
  1856.                 (*theFunc)(prefs, dlg, kInit);
  1857.                 DlgSetDefaultButtonOutline(dlg, 
  1858.                     curTopic != kSignature && curTopic != kExtraHeaderLines);
  1859.             }
  1860.         } else {
  1861.             (*theFunc)(prefs, dlg, item);
  1862.         }
  1863.     }
  1864.     
  1865.     SaveMovableModalDialogPosition(dlg, &newLocn);
  1866.     
  1867.     err = DoClose(dlg);
  1868.     if (err != noErr) goto exit;
  1869.     
  1870.     if (item == ok) {
  1871.         if (prefs->logActionsToFile && !gPrefs.logActionsToFile) {
  1872.             OpenLogFile();
  1873.         } else if (!prefs->logActionsToFile && gPrefs.logActionsToFile) {
  1874.             CloseLogFile();
  1875.         }
  1876.         if (!EqualString(prefs->newsServerName, gPrefs.newsServerName, false, true)) {
  1877.             NoteMessageNumber(kStrMustRestart);
  1878.         }
  1879.         if (prefs->useInternetConfig != gPrefs.useInternetConfig) {
  1880.             NoteMessageNumber(kStrMustRestartIC);
  1881.         }
  1882.         reauthenticate = strcmp(prefs->authUsername, gPrefs.authUsername) != 0 ||
  1883.             strcmp(prefs->authPassword, gPrefs.authPassword) != 0 ||
  1884.             prefs->authAtStartup && !gPrefs.authAtStartup;
  1885.         MyDisposeHandle(gPrefs.savedMsgDefaultFolderAlias);
  1886.         MyDisposeHandle(gPrefs.savedArtDefaultFolderAlias);
  1887.         MyDisposeHandle(gPrefs.savedBinDefaultFolderAlias);
  1888.         MyDisposeHandle(gPrefs.savedUGLDefaultFolderAlias);
  1889.         gPrefs = *prefs;
  1890.         MyICWriteSharedPrefs(kICAllSharedPrefs);
  1891.         ResetNewsServerOptions();
  1892.         AdjustExtractBinariesCommand();
  1893.     } else {
  1894.         MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  1895.         MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  1896.         MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  1897.         MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  1898.     }
  1899.     MyDisposePtr(prefs);
  1900.     prefs = nil;
  1901.     gPrefs.prefsLoc = newLocn;
  1902.     if (reauthenticate && gStartupOK) {
  1903.         err = ReAuthenticate();
  1904.         if (err != noErr) goto exit;
  1905.         if (gPrefs.authPrivateGroups) {
  1906.             err = DoRebuildFullGroupList();
  1907.             if (err != noErr) goto exit;
  1908.         }
  1909.     }
  1910.     SetPort(port);
  1911.     return noErr;
  1912.     
  1913. exit:
  1914.  
  1915.     if (prefs != nil) {
  1916.         MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  1917.         MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  1918.         MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  1919.         MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  1920.         MyDisposePtr(prefs);
  1921.     }
  1922.     SetPort(port);
  1923.     return err;
  1924. }
  1925.  
  1926.  
  1927.  
  1928. /*----------------------------------------------------------------------------
  1929.     prefsdlog_InitUPP
  1930.     
  1931.     Initialize UPPs.
  1932. ----------------------------------------------------------------------------*/
  1933.  
  1934. void prefsdlog_InitUPP (void)
  1935. {
  1936.     gInvisibleFilesFilterUPP = NewFileFilterYDProc(InvisibleFilesFilter);
  1937.     gDrawFontSampleUPP = NewUserItemProc(DrawFontSample);
  1938. }